#ifndef __RANK_MGR_H__
#define __RANK_MGR_H__

#include <vector>
#include <map>
#include <time.h>
#include <string>
#include "dbmgr.h"
#include "proto_20000_rank.h"
#include "common_def.h"

class GlobalServer;

struct RankData
{
	RankData()
	{
		struct timeval tv;
		gettimeofday(&tv, NULL);
		record_time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
	}

	~RankData()
	{
		items.clear();
	}

	int uid;
	int level;
	int vip;
	std::string nick;
	std::string facelook;
	std::string sign;
	std::string channel;
	time_t tt;
	int start_time;
	int end_time;
	long record_time; //记录的时间
	std::map<int, long> items;
	MSGPACK_DEFINE(uid, level, vip, nick, facelook, sign, tt, items, start_time, end_time);
};

#define RANK_TYPE_JB 3		 				// 金币榜
#define RANK_TYPE_DJ 6		 				// 等级榜
#define RANK_TYPE_DT 7		 				// 弹头榜
#define RANK_TYPE_MJ 8		 				// 魔晶榜
#define RANK_TYPE_ZQJF 9		 			// 中秋幸运值排行榜
#define RANK_TYPE_JFD 10     			// 花色积分日榜
#define RANK_TYPE_JFW 11     			// 花色积分周榜
#define RANK_TYPE_DTJF 12     		// 弹头欢乐炸积分榜
#define RANK_TYPE_MATERIAL 13     // 材料榜
#define RANK_TYPE_GQJF 14     		// 国庆幸运值排行榜
#define RANK_TYPE_DAY_BOTTLE 16   // 酒瓶日排行
#define RANK_TYPE_WEEK_BOTTLE 17  // 酒瓶周排行   
#define RANK_TYPE_DAY_RECHARGE 19  // 活动日充值排行

#define RANK_TYPE_PET_DOG_DAY 20    // 宠物小八犬日榜
#define RANK_TYPE_PET_MONKEY_DAY 21 // 宠物猴子日榜
#define RANK_TYPE_PET_DRAGON_DAY 22 // 宠物龙日榜

#define RANK_TYPE_PET_DOG_WEEK 23    // 宠物小八犬周榜
#define RANK_TYPE_PET_MONKEY_WEEK 24 // 宠物猴子周榜
#define RANK_TYPE_PET_DRAGON_WEEK 25 // 宠物龙周榜

#define RANK_MATCH_AP_DAY 26 //全民赛日榜
#define RANK_MATCH_BP_DAY 27 //大奖赛日榜
#define RANK_MATCH_BP_WEEK 28 //大奖赛周榜
#define RANK_GS_WEEK 29       //猜大小周榜
#define RANK_EGG_ACTIVITY 30  //扭蛋活动排行榜
#define RANK_DRAGON_JACKPOT 31 //金龙奖池
#define RANK_JADE_MATCH_DAY 32 //玉石比赛日排行
#define RANK_JADE_MATCH_WEEK 33 //玉石比赛周期排行

//#define RANK_BOSS_HY_LUCKY_DAY 34 //海妖好运榜
//#define RANK_BOSS_HY_COMFORT_DAY 35 //海妖安慰榜  
#define RANK_BOSS_DYSW_LUCKY_DAY 36 //地狱守卫好运榜
#define RANK_BOSS_DYSW_COMFORT_DAY 37 //地狱守卫安慰榜

#define DEFAULT_RANK_SIZE 20
#define JB_ID 10010001		// 金币ID
#define MJ_ID 20070003		// 魔晶ID
#define BJDT_ID 20010004	// 铂金弹头
#define HJDT_ID 20010003	// 黄金弹头
#define BYDT_ID 20010002	// 白银弹头
#define QTDT_ID 20010001	 // 青铜弹头
#define HSJF_ID 10010009   // 花色积分
#define BOTTLE_ID 20090001 // 酒瓶积分
#define STONE_ID 20070001 	// 强化石
#define ESSENCE_ID 20070002 // 原石精华
#define LUCKY_VALUE_ID 10010007    // 幸运值
#define DTJF_ID 10010010    		// 弹头积分
#define DAY_RECHARGE_ID 10010013    // 活动日充值积分
#define PET_INTEGRAL_ID 40020001    //宠物积分
#define MATCH_INTEGRAL_ID 10010008  //比赛积分
#define GS_INTEGRAL_ID 10010009 //猜大小积分ID
#define EGG_INTEGRAL_ID 10010020 //扭蛋活动积分
#define DRAGON_JACKPOT_INTEGRAL_ID 10010021 //金龙奖池积分
#define REAL_RANK 0x01
#define SHOW_RANK 0x10
#define SECONDS_OF_HOUR 3600
#define SECONDS_OF_DAY (24 * SECONDS_OF_HOUR)
#define SECONDS_OF_WEEK (7 * SECONDS_OF_DAY)
#define RANK_FRESH_INTERVAL SECONDS_OF_HOUR

const int DT[] = {BJDT_ID, HJDT_ID, BYDT_ID, QTDT_ID};
const int CL[] = {STONE_ID, ESSENCE_ID};
#define DT_NUM (sizeof(DT) / sizeof(DT[0]))
#define CL_NUM (sizeof(CL) / sizeof(CL[0]))
#define BOSS_NUM 2
//static int BOSS_HY_HID[] = {RANKTYPE_HY_LUCKY_DAY, RANKTYPE_HY_BOSS_ID};
//static int BOSS_HY_LID[] = {RANKTYPE_HY_COMFORT_DAY, RANKTYPE_HY_BOSS_ID};
static int BOSS_DYSW_HID[] = {RANKTYPE_DYSW_LUCKY_DAY,RANKTYPE_DYSW_BOSS_ID};
static int BOSS_DYSW_LID[] = {RANKTYPE_DYSW_COMFORT_DAY, RANKTYPE_DYSW_BOSS_ID};

typedef bool(*CmpFunc)(const RankData &r1, const RankData &r2);

class Rank
{
public:
	Rank(int type, CmpFunc func, GlobalServer *pServer);

	virtual ~Rank();

public:
	virtual int add(const RankData &rd);

	virtual void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2) = 0;

	virtual int filter();

	virtual int fresh(time_t now);

	virtual void init();

	virtual int getRankSize();

    virtual bool isOpen();
public:
	int getType();

    void setType(int type);

	void serialize(std::string &str);

	void unserialize(const std::string &real_data, const std::string &show_data);

	void setInsertFlag(bool flag);

	bool needInsert();

	void sort();
	
	int getNextFreshTime();

	void setRankIndex(const int &nMin, const int &nMax);
	
	int getTopRank();

	void setUid(const int &nUid);

	int getCurRankSize();

	void printRank(bool bOnlyReal = true);

	//20190529改成写mysql，每个排行榜自己写
	void saveRank();
	void saveRank(int nType);

	//20190529改成写mysql，每个排行榜自己写
	//发榜的时候把榜单写到历史表，可供查询
	void saveRankHistory();

	void initFromDB();

	//发榜后清除数据库的榜单数据
	void clearRankDB();
	
private:
	void serialize(int type, std::string &data);
	void unserialize(int type, const std::string &data);

	void readFromDb(int nType, int nSortNo);

private:
	int m_insert;
	CmpFunc m_cmp;
public:
	int m_type;

protected:
	int m_nRankMin;
	int m_nRankMax;
	int m_nTopRank;
	int m_uid;
	int m_next_fresh;
	GlobalServer *m_pServer;
	std::vector<RankData> m_real;
	std::vector<RankData> m_show;
	std::map<int, int> m_userRank;
	std::vector<int> m_clientRank;
	base::Logger *m_pRollLog;
};

// 金币排行榜
class JBRank : public Rank
{
public:
	JBRank(CmpFunc func, GlobalServer *pServer);
	~JBRank();

public:
	int add(const RankData &rd);

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

// 等级排行榜
class DJRank : public Rank
{
public:
	DJRank(CmpFunc func, GlobalServer *pServer);

	~DJRank();

public:
	int add(const RankData &rd);

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

// 弹头排行榜
class DTRank : public Rank
{
public:
	DTRank(CmpFunc func, GlobalServer *pServer);

	~DTRank();

public:
	int add(const RankData &rd);

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

// 魔晶排行榜
class MJRank : public Rank
{
public:
	MJRank(CmpFunc func, GlobalServer *pServer);

	~MJRank();

public:
	int add(const RankData &rd);

	int fresh(time_t now);

	void updateHaiMoRankFreshTime(int nTime);

	void init();

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

// 花色积分日榜
class HSJFDRank : public Rank
{
public:
    HSJFDRank(CmpFunc func, GlobalServer *pServer);

	~HSJFDRank();

public:
	int add(const RankData &rd);

	int fresh(time_t now);

	void init();

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);

};

// 花色积分周榜
class HSJFWRank : public HSJFDRank
{
public:
    HSJFWRank(CmpFunc func, GlobalServer *pServer);

	~HSJFWRank();

public:
	void init();

	int add(const RankData &rd);

    int fresh(time_t now);
};

//酒瓶积分日榜
class BottleDayRank : public Rank
{
public:
	BottleDayRank(CmpFunc func, GlobalServer *pServer);
	~BottleDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};
//酒瓶积分周榜
class BottleWeekRank : public BottleDayRank
{
public:
	BottleWeekRank(CmpFunc func, GlobalServer *pServer);
	~BottleWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};


//日充值积分日榜
class RechargeDayRank : public Rank
{
public:
	RechargeDayRank(CmpFunc func, GlobalServer *pServer);
	~RechargeDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};


// 中秋幸运值排行榜
class ZQJFRank : public Rank 
{
public:
    ZQJFRank(CmpFunc func, GlobalServer *pServer);

	~ZQJFRank();

public:
	void init();

	int add(const RankData &rd);

    int fresh(time_t now);
	
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);

};

// 国庆幸运值排行榜
class GQJFRank : public ZQJFRank
{
public:
    GQJFRank(CmpFunc func, GlobalServer *pServer);

	~GQJFRank();

public:
	void init();

	int add(const RankData &rd);
};

// 弹头炸积分排行榜
class DTJFRank : public ZQJFRank
{
public:
    DTJFRank(CmpFunc func, GlobalServer *pServer);

	~DTJFRank();

public:
	void init();

	int add(const RankData &rd);
	
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

// 材料排行榜
class CLRank : public Rank
{
public:
	CLRank(CmpFunc func, GlobalServer *pServer);

	~CLRank();

public:
	int add(const RankData &rd);

	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};



//宠物犬排行
class PetDogDayRank : public Rank
{
public:
	PetDogDayRank(CmpFunc func, GlobalServer *pServer);
	~PetDogDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

class PetDogWeekRank : public PetDogDayRank
{
public:
	PetDogWeekRank(CmpFunc func, GlobalServer *pServer);
	~PetDogWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};





//宠物猴子排行
class PetMonkeyDayRank : public Rank
{
public:
	PetMonkeyDayRank(CmpFunc func, GlobalServer *pServer);
	~PetMonkeyDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

class PetMonkeyWeekRank : public PetMonkeyDayRank
{
public:
	PetMonkeyWeekRank(CmpFunc func, GlobalServer *pServer);
	~PetMonkeyWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};


//宠物龙排行
class PetDragonDayRank : public Rank
{
public:
	PetDragonDayRank(CmpFunc func, GlobalServer *pServer);
	~PetDragonDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

class PetDragonWeekRank : public PetDragonDayRank
{
public:
	PetDragonWeekRank(CmpFunc func, GlobalServer *pServer);
	~PetDragonWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};


//全民赛日榜
class AllPeopleMatchDayRank : public Rank
{
public:
	AllPeopleMatchDayRank(CmpFunc func, GlobalServer *pServer);
	~AllPeopleMatchDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

//大奖赛日榜
class BigPrizeMatchDayRank : public AllPeopleMatchDayRank
{
public:
	BigPrizeMatchDayRank(CmpFunc func, GlobalServer *pServer);
	~BigPrizeMatchDayRank();
	int add(const RankData &rd);
};

//大奖赛周榜
class BigPrizeMatchWeekRank : public BigPrizeMatchDayRank
{
public:
	BigPrizeMatchWeekRank(CmpFunc func, GlobalServer *pServer);
	~BigPrizeMatchWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};


//猜大小周榜
class GuessSizeRank : public Rank
{
public:
	GuessSizeRank(CmpFunc func, GlobalServer *pServer);
	~GuessSizeRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

//扭蛋活动积分排行榜
class EggActivityRank : public Rank
{
public:
	EggActivityRank(CmpFunc func, GlobalServer *pServer);
	~EggActivityRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

//金龙奖池
class DragonJackpotRank : public Rank
{
public:
	DragonJackpotRank(CmpFunc func, GlobalServer *pServer);
	~DragonJackpotRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

//玉石比赛日排行 
class JadeMatchDayRank:public Rank
{
public:
	JadeMatchDayRank(CmpFunc func, GlobalServer *pServer);
	~JadeMatchDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
	bool inActivityTime();

	int m_nBeginTime;
	int m_nEndTime;
};

//玉石比赛周排行
class JadeMatchWeekRank:public JadeMatchDayRank
{
public:
	JadeMatchWeekRank(CmpFunc func, GlobalServer *pServer);
	~JadeMatchWeekRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
};

/*//海妖好运日榜
class LuckyBossHyDayRank:public Rank
{
public:
	LuckyBossHyDayRank(int rankType, CmpFunc func, GlobalServer *pServer);
	~LuckyBossHyDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};
//海妖安慰日榜
class ComfortBossHyDayRank:public LuckyBossHyDayRank
{
public:
	ComfortBossHyDayRank(int rankType, CmpFunc func, GlobalServer *pServer);
	~ComfortBossHyDayRank();

	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};*/
//守卫好运日榜
class LuckyBossDyswDayRank:public Rank
{
public:
	LuckyBossDyswDayRank(int rankType, CmpFunc func, GlobalServer *pServer);
	~LuckyBossDyswDayRank();

	void init();
	int fresh(time_t now);
	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};
//守卫安慰日榜
class ComfortBossDyswDayRank:public LuckyBossDyswDayRank
{
public:
	ComfortBossDyswDayRank(int rankType, CmpFunc func, GlobalServer *pServer);
	~ComfortBossDyswDayRank();

	int add(const RankData &rd);
	void getRankList(std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);
};

class RankMgr
{
public:
	RankMgr();

	~RankMgr();

private:
	RankMgr(const RankMgr &rhs);

	RankMgr &operator=(const RankMgr &rhs);

public:
	void init(base::FileConfig &confMgr, base::Logger *pLogger, GlobalServer *pServer);

	void fresh(time_t now);

	void add(const RankData &rd);

	void getRankList(int type, std::vector<proto20rank::proto_rank_data> &v1, std::vector<proto20rank::proto_rank_data> &v2);

	void reload();

	void setRankIndex(const int nType, const int &nMin, const int &nMax);

	int getTopRank(const int nType);

	void setUid(const int nType, const int &nUid);

	int getRankSize(const int nType);

private:
	Rank *createRank(int type, CmpFunc func, GlobalServer *pServer);

	Rank *getRank(int type);

	void saveRank(Rank *p);

private:
	DBMgr *m_pDbMgr;
	base::Logger *m_pRollLog;
	std::map<int, Rank *> m_ranks;
};
#endif
